package com.zbkj.crmeb.handler.orderproduct;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.crmeb.core.exception.CrmebException;
import com.doudian.open.api.material_batchUploadImageSync.MaterialBatchUploadImageSyncRequest;
import com.doudian.open.api.material_batchUploadImageSync.MaterialBatchUploadImageSyncResponse;
import com.doudian.open.api.material_batchUploadImageSync.data.SuccessMapItem;
import com.doudian.open.api.material_batchUploadImageSync.param.MaterialBatchUploadImageSyncParam;
import com.doudian.open.api.material_batchUploadImageSync.param.MaterialsItem;
import com.doudian.open.api.material_queryMaterialDetail.MaterialQueryMaterialDetailRequest;
import com.doudian.open.api.material_queryMaterialDetail.MaterialQueryMaterialDetailResponse;
import com.doudian.open.api.material_queryMaterialDetail.data.MaterialInfo;
import com.doudian.open.api.material_queryMaterialDetail.param.MaterialQueryMaterialDetailParam;
import com.doudian.open.api.materialgw.upload.BinaryMaterialUploadParam;
import com.doudian.open.api.materialgw.upload.BinaryMaterialUploadResponseWrapper;
import com.doudian.open.api.product_addV2.ProductAddV2Request;
import com.doudian.open.api.product_addV2.ProductAddV2Response;
import com.doudian.open.api.product_addV2.data.ProductAddV2Data;
import com.doudian.open.api.product_addV2.data.SkuItem;
import com.doudian.open.api.product_addV2.param.*;
import com.doudian.open.api.product_getProductUpdateRule.ProductGetProductUpdateRuleRequest;
import com.doudian.open.api.product_getProductUpdateRule.ProductGetProductUpdateRuleResponse;
import com.doudian.open.api.product_getProductUpdateRule.param.ProductGetProductUpdateRuleParam;
import com.doudian.open.api.supplyChain_publishProduct.SupplyChainPublishProductRequest;
import com.doudian.open.api.supplyChain_publishProduct.SupplyChainPublishProductResponse;
import com.doudian.open.api.supplyChain_publishProduct.data.Data;
import com.doudian.open.api.supplyChain_publishProduct.param.*;
import com.doudian.open.api.supplyChain_queryCargoList.SupplyChainQueryCargoListRequest;
import com.doudian.open.api.supplyChain_queryCargoList.SupplyChainQueryCargoListResponse;
import com.doudian.open.api.supplyChain_queryCargoList.data.CargoListItem;
import com.doudian.open.api.supplyChain_queryCargoList.param.SupplyChainQueryCargoListParam;
import com.doudian.open.api.supplyChain_uploadImage.SupplyChainUploadImageRequest;
import com.doudian.open.api.supplyChain_uploadImage.SupplyChainUploadImageResponse;
import com.doudian.open.api.supplyChain_uploadImage.param.SupplyChainUploadImageParam;
import com.doudian.open.api.warehouse_list.WarehouseListRequest;
import com.doudian.open.api.warehouse_list.WarehouseListResponse;
import com.doudian.open.api.warehouse_list.data.WarehousesItem;
import com.doudian.open.api.warehouse_list.param.Addr;
import com.doudian.open.api.warehouse_list.param.WarehouseListParam;
import com.doudian.open.core.AccessToken;
import com.doudian.open.core.AccessTokenBuilder;
import com.doudian.open.core.material.BinaryMaterialUpload;
import com.doudian.open.core.material.BinaryMaterialUploadExecutor;
import com.factory.PushWarehouseFactory;
import com.utils.PriceUtil;
import com.zbkj.crmeb.chant.model.CategoryMatch;
import com.zbkj.crmeb.chant.model.ChannelMerchant;
import com.zbkj.crmeb.chant.service.ICategoryMatchService;
import com.zbkj.crmeb.enums.AreaTypeEnum;
import com.zbkj.crmeb.enums.BusinessTypeEnums;
import com.zbkj.crmeb.enums.plat.PlatPushStatusEnums;
import com.zbkj.crmeb.merchant.api.service.MerProductService;
import com.zbkj.crmeb.plat.by.dto.ByCommonConstant;
import com.zbkj.crmeb.plat.by.dto.Result;
import com.zbkj.crmeb.plat.by.dto.TikTokPushInfo;
import com.zbkj.crmeb.plat.enums.MerPlatEnums;
import com.zbkj.crmeb.store.model.*;
import com.zbkj.crmeb.store.service.*;
import com.zbkj.crmeb.task.plat.tiktok.TikTokApi;
import com.zbkj.crmeb.tools.model.MoneyExchange;
import com.zbkj.crmeb.tools.service.MoneyExchangeService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: wsl
 * @date: 2024/2/22 0022 22:28
 * @ClassName: tikTokOrderProductHandler
 */
@Component("tikTokOrderProductHandler")
public class TikTokOrderProductHandler extends AbstractOrderProductHandler {
    @Autowired
    private StoreOrderService storeOrderService;
    @Autowired
    private StoreOrderInfoService storeOrderInfoService;
    @Autowired
    private StoreProductService storeProductService;
    @Autowired
    private StoreProductAttrValueService storeProductAttrValueService;
    @Autowired
    private StoreProductAttrService storeProductAttrService;
    @Autowired
    private StoreProductDescriptionService storeProductDescriptionService;
    @Autowired
    private MerProductService productService;
    @Autowired
    private MoneyExchangeService moneyExchangeService;
    @Autowired
    private StoreProductLogService storeProductLogService;
    @Autowired
    private ICategoryMatchService categoryMatchService;
    @Autowired
    private StoreBrandService storeBrandService;
    @Autowired
    private PushWarehouseFactory pushWarehouseFactory;
    @Autowired
    private RelationService relationService;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private PriceUtil priceUtil;

    private static final Logger logger = LoggerFactory.getLogger(TikTokOrderProductHandler.class);

    @Override
    public boolean doPreCheck(OrderProductContext context) {
        return true;
    }

    @Override
    public Result doHandler(OrderProductContext context) {
        Result result = new Result();
        String productId = context.getProductId();
        context.getTikTokPushInfo().setMerId(context.getMerId());
        // 查询商品信息
        StoreProduct storeProduct = context.getStoreProduct();
        if (null == storeProduct) {
            storeProduct = storeProductService.getById(productId);
            context.setStoreProduct(storeProduct);
        }
        // 查询sku信息
        List<StoreProductAttrValue> storeProductAttrValues = context.getStoreProductAttrValues();
        if (CollectionUtils.isEmpty(storeProductAttrValues)) {
            storeProductAttrValues = storeProductAttrValueService.getListByProductId(Integer.valueOf(productId));
            context.setStoreProductAttrValues(storeProductAttrValues);
        }
        List<String> validateList = new ArrayList<>();
        // 获取Token
        AccessToken accessToken = AccessTokenBuilder.build(TikTokApi.getShopId(context.getMerId()));
        // 1 发布货品 多个规格
        publishCargo(context, storeProduct, storeProductAttrValues, validateList, accessToken);
        if (CollectionUtils.isNotEmpty(validateList)) {
            result.setSuccess(false);
            result.setData(validateList);
            return result;
        }
//        ArrayList<JSONObject> publishCargoDataList = new ArrayList<>();
//        publishCargoDataList.add(JSON.parseObject("{\"results\":[{\"cargo_code\":7373625897997631763,\"external_cargo_code\":\"185632765_2812578\"}]}"));
//        context.setPublishCargoDataList(publishCargoDataList);
        // 2 发布商品
        publishProduct(context, storeProduct, storeProductAttrValues, validateList, accessToken);
        if (CollectionUtils.isNotEmpty(validateList)) {
            result.setSuccess(false);
            result.setData(validateList);
            return result;
        }
        result.setSuccess(true);
        result.setData(validateList);
        return result;
    }

    private void publishCargo(OrderProductContext context, StoreProduct storeProduct, List<StoreProductAttrValue> storeProductAttrValues, List<String> validateList, AccessToken accessToken) {
        // 1.1 初始化 请求对象
        SupplyChainPublishProductRequest request = new SupplyChainPublishProductRequest();
        SupplyChainPublishProductParam param = request.getParam();
        List<JSONObject> publishCargoDataList = new ArrayList<>();

        for (StoreProductAttrValue storeProductAttrValue : storeProductAttrValues) {
            try {
                Thread.sleep((int) (Math.random() * 1000) + 500);
            } catch (Exception e) {
                logger.error(e.getClass().getName() + "线程休眠异常");
            }
            // 查询 如果存在就不上传了
            TikTokPushInfo tikTokPushInfo = context.getTikTokPushInfo();
            SupplyChainQueryCargoListRequest queryRequest = new SupplyChainQueryCargoListRequest();
            SupplyChainQueryCargoListParam queryParam = queryRequest.getParam();
            queryParam.setPageNo(1L);
            queryParam.setPageSize(1L);
            queryParam.setCargoBarcode(storeProduct.getKeyword() + "_" + storeProductAttrValue.getId());
//            queryParam.setCargoCategoryId(tikTokPushInfo.getCategoryId());
            queryParam.setBmpCode("xiaodian.crossborder");
            SupplyChainQueryCargoListResponse queryRes = queryRequest.execute(accessToken);
            logger.info("publishCargo抖店推送【创建货品】入参=====>>>" + JSON.toJSONString(queryParam));
            logger.info("publishCargo抖店推送【创建货品】响应=====>>>" + JSON.toJSONString(queryRes));

            if (queryRes.isSuccess() && queryRes.getData().getTotal() != 0) {
                CargoListItem cargoListItem = queryRes.getData().getCargoList().get(0);
                JSONObject jsonObject = new JSONObject();
                JSONArray value = new JSONArray();
                JSONObject e = new JSONObject();
                e.put("cargoCode", cargoListItem.getCargoCode());
                e.put("externalCargoCode", cargoListItem.getExternalCargoCode());
                value.add(e);
                jsonObject.put("results", value);
                jsonObject.put("attr_value_id", storeProductAttrValue.getId());
                publishCargoDataList.add(jsonObject);
                continue;
            }
            // 1.2 组装请求对象
            assembledCargo(param, context, storeProduct, storeProductAttrValue, validateList, accessToken);
            // 1.3 发送请求
            SupplyChainPublishProductResponse response = request.execute(accessToken);
            // 1.4 验证请求结果有效性并保存数据
            if (response.isSuccess()) {
                Data data = response.getData().getData();
                String jsonString = JSON.toJSONString(data);
                JSONObject jsonObject = JSON.parseObject(jsonString);
                jsonObject.put("attr_value_id", storeProductAttrValue.getId());
                publishCargoDataList.add(jsonObject);
            } else {
                validateList.add(response.getMsg() + "," + response.getSubMsg());
            }
        }
        context.setValidateList(validateList);
        context.setPublishCargoDataList(publishCargoDataList);
    }

    private void publishProduct(OrderProductContext context, StoreProduct storeProduct, List<StoreProductAttrValue> storeProductAttrValues, List<String> validateList, AccessToken accessToken) {
        ProductAddV2Request request = new ProductAddV2Request();
        // 2.1 初始化 请求对象
        ProductAddV2Param param = request.getParam();
        // 2.2 组装请求对象
        assembledProduct(param, context, storeProduct, storeProductAttrValues, validateList, accessToken);
        // 2.3 发送请求
        ProductAddV2Response response = request.execute(accessToken);
        logger.info("publishProduct抖店推送【创建商品】入参=====>>>" + JSON.toJSONString(request));
        logger.info("publishProduct抖店推送【创建商品】响应=====>>>>" + JSON.toJSONString(response));
        // 2.4 验证请求结果有效性并保存数据
        if (response.isSuccess()) {
            ProductAddV2Data data = response.getData();
            String jsonString = JSON.toJSONString(data);
            context.setPublishProductParam(param);
            context.setPublishProductData(data);
        } else {
            param.setCommit(false);
            ProductAddV2Response responseAgain = request.execute(accessToken);
            if (responseAgain.isSuccess()) {
                ProductAddV2Data data = responseAgain.getData();
                String jsonString = JSON.toJSONString(data);
                context.setPublishProductParam(param);
                context.setPublishProductData(data);
            } else {
                validateList.add(response.getMsg() + "," + response.getSubMsg());
                validateList.add(responseAgain.getMsg() + "," + responseAgain.getSubMsg());
            }
        }
        context.setValidateList(validateList);
    }

    private void matchCategoryAndBrand(OrderProductContext context, StoreProduct storeProduct) {
        Integer cateId = storeProduct.getCateId();
        Integer brandId = storeProduct.getBrandId();
        if (null == cateId || null == brandId) {
            throw new CrmebException("商品分类或者品牌缺失");
        }
        CategoryMatch categoryMatch = categoryMatchService.getById(cateId);
        if (null != categoryMatch) {
            context.setCategoryId(categoryMatch.getByCategoryId());
        }
        StoreBrand storeBrand = storeBrandService.getById(brandId);
        if (null != storeBrand) {
            context.setBrandId(storeBrand.getByBrandId());
        }

    }

    @Override
    public void doAfter(OrderProductContext context, Result result) {
        // 处理商品数据
        handleProductAfter(context, result);
        // 处理SKU数据
        handleSkuAfter(context, result);
    }

    private void handleProductAfter(OrderProductContext context, Result result) {
        StoreProduct storeProduct = context.getStoreProduct();
        List<JSONObject> publishCargoDataList = context.getPublishCargoDataList();
        ProductAddV2Data publishProductData = context.getPublishProductData();
        // 更新推送标记
        String pushPlat = result.isSuccess() ? ByCommonConstant.TIKTOK_UP : PlatPushStatusEnums.PUSH_FAIL.getCode();
        Relation productRelation = relationService.getOne(Wrappers.<Relation>lambdaQuery().eq(Relation::getBusinessCode, storeProduct.getId()).eq(Relation::getBusinessType, BusinessTypeEnums.PUSH_PRODUCT_PLAT_OF_DY.getCode()));
        if (null == productRelation) {
            productRelation = Relation.buildRelation(String.valueOf(storeProduct.getId()), BusinessTypeEnums.PUSH_PRODUCT_PLAT_OF_DY, pushPlat);
        }
        productRelation.setSubCode(pushPlat);
        String msg = result.isSuccess() ? "商品推送抖店平台成功" : "推送失败:" + result.getMessage();
        if (null != publishProductData) {
            productRelation.addFeature(ByCommonConstant.DY_PRODUCT_ID, publishProductData.getProductId().toString());
            productRelation.addFeature(ByCommonConstant.DY_OUT_PRODUCT_ID, publishProductData.getOutProductId().toString());
            productRelation.addFeature(ByCommonConstant.DY_OUTER_PRODUCT_ID, publishProductData.getOuterProductId());
        }
        if (null == productRelation.getId()) {
            relationService.save(productRelation);
        } else {
            relationService.updateById(productRelation);
        }
        List<String> validateList = context.getValidateList();
        // 保存日志
        List<StoreProductLog> storeProductLogs = new ArrayList<>();
        storeProductLogs.add(StoreProductLog.assembledLog(String.valueOf(storeProduct.getId()), msg));
        validateList.forEach(item -> storeProductLogs.add(StoreProductLog.assembledLog(String.valueOf(storeProduct.getId()), item)));
        storeProductLogService.saveOrUpdateBatch(storeProductLogs);
    }

    private void handleSkuAfter(OrderProductContext context, Result result) {
        List<JSONObject> publishCargoDataList = context.getPublishCargoDataList();
        ProductAddV2Data publishProductData = context.getPublishProductData();
        ProductAddV2Param publishProductParam = context.getPublishProductParam();
        if (CollectionUtils.isEmpty(publishCargoDataList) || Objects.isNull(publishProductData) || Objects.isNull(publishProductParam)) {
            return;
        }
        List<SpecPricesV2Item> specPricesV2 = publishProductParam.getSpecPricesV2();
        List<StoreProductAttrValue> storeProductAttrValues = context.getStoreProductAttrValues();
        if (CollectionUtils.isEmpty(storeProductAttrValues)) {
            return;
        }
        Map<Integer, StoreProductAttrValue> map = new HashMap<>();
        List<String> attrValueIds = new ArrayList<>();
        for (StoreProductAttrValue storeProductAttrValue : storeProductAttrValues) {
            map.put(storeProductAttrValue.getId(), storeProductAttrValue);
            attrValueIds.add(String.valueOf(storeProductAttrValue.getId()));
        }
        List<Relation> relations = relationService.list(Wrappers.<Relation>lambdaQuery().in(Relation::getBusinessCode, attrValueIds).eq(Relation::getBusinessType, BusinessTypeEnums.PUSH_SKU_PLAT_OF_BY.getCode()));
        Map<String, Relation> relationMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(relations)) {
            relationMap = relations.stream().collect(Collectors.toMap(Relation::getBusinessCode, v -> v));
        }
        Map<Long, SpecPricesV2Item> pricesV2ItemMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(specPricesV2)) {
            pricesV2ItemMap = specPricesV2.stream().collect(Collectors.toMap(SpecPricesV2Item::getOutSkuId, v -> v));
        }
        List<Relation> updateRelations = new ArrayList<>();
        List<Relation> insertRelations = new ArrayList<>();
        for (SkuItem skuItem : publishProductData.getSku()) {
            Long outSkuId = skuItem.getOutSkuId();
            StoreProductAttrValue storeProductAttrValue = map.get(outSkuId.intValue());
            Relation skuRelation = relationMap.get(outSkuId.toString());
            if (null == skuRelation) {
                skuRelation = Relation.buildRelation(outSkuId.toString(), BusinessTypeEnums.PUSH_SKU_PLAT_OF_DY, ByCommonConstant.TIKTOK_UP);
                insertRelations.add(skuRelation);
            } else {
                updateRelations.add(skuRelation);
            }
            skuRelation.addFeature(ByCommonConstant.PUSH_PLAT, "Y");
            skuRelation.addFeature(ByCommonConstant.ORIGIN_STOCK, String.valueOf(storeProductAttrValue.getStock()));
            skuRelation.addFeature(ByCommonConstant.PUSH_PRICE, String.valueOf(storeProductAttrValue.getPrice()));

            skuRelation.addFeature(ByCommonConstant.DY_SKU_ID, skuItem.getSkuId().toString());
            skuRelation.addFeature(ByCommonConstant.DY_OUT_SKU_ID, skuItem.getOutSkuId().toString());
            skuRelation.addFeature(ByCommonConstant.DY_OUTER_SKU_ID, skuItem.getOuterSkuId());

            SpecPricesV2Item specPricesV2Item = pricesV2ItemMap.get(skuItem.getOutSkuId());
            if (null != specPricesV2Item) {
                skuRelation.addFeature(ByCommonConstant.PLAT_SALE_PRICE, String.valueOf(specPricesV2Item.getPrice()));
                skuRelation.addFeature(ByCommonConstant.PLAT_ORIGINAL_PRICE, String.valueOf(specPricesV2Item.getSupplyPrice()));
            }

        }
        if (CollectionUtils.isNotEmpty(updateRelations)) {
            for (Relation updateRelation : updateRelations) {
                relationService.updateById(updateRelation);
            }
        }
        if (CollectionUtils.isNotEmpty(insertRelations)) {
            relationService.saveBatch(insertRelations);
        }
    }

    private void assembledCargo(SupplyChainPublishProductParam param, OrderProductContext context, StoreProduct storeProduct, StoreProductAttrValue storeProductAttrValue, List<String> validateList, AccessToken accessToken) {
        TikTokPushInfo tikTokPushInfo = context.getTikTokPushInfo();
        com.doudian.open.api.supplyChain_queryCatePropList.data.Data catePropData;
        param.setBmpCode("xiaodian.crossborder"); // 行业身份（跨境pop：xiaodian.crossborder）
        param.setItemType(1);// 货品类型 1:普通货品 2:配件 6:包材 7:耗材
        param.setProductName(tikTokPushInfo.getProductName() + " " + storeProductAttrValue.getSuk());// 货品名称
        param.setProductDesc(storeProduct.getStoreName() + " " + storeProduct.getKeyword() + " " + storeProductAttrValue.getSuk());// 货品描述
        param.setCargoCategoryId(tikTokPushInfo.getCategoryId());

        List<CategoryPropsItem> categoryProps = new ArrayList<>();
        for (TikTokPushInfo.Prop prop : tikTokPushInfo.getTikTokCategoryPropList()) {
            CategoryPropsItem item = new CategoryPropsItem();
            PropKey propKey = new PropKey();
            propKey.setPropKeyId(prop.getPropKey().getPropKeyId());
            propKey.setPropKey(prop.getPropKey().getPropKey());
            propKey.setPropCode(prop.getPropKey().getPropCode());
            item.setPropKey(propKey);

            if (prop.getIsMulti()) {
                List<PropValListItem> propValList = new ArrayList<>();
                PropValListItem propValListItem = new PropValListItem();
                propValListItem.setPropValueId(prop.getPropVal().getPropValueId());
                propValListItem.setPropValue(prop.getPropVal().getPropValue());
                propValList.add(propValListItem);
                item.setPropValList(propValList);
            } else {
                PropVal propVal = new PropVal();
                propVal.setPropValueId(prop.getPropVal().getPropValueId());
                propVal.setPropValue(prop.getPropVal().getPropValue());
                item.setPropVal(propVal);
            }
            item.setIsMulti(prop.getIsMulti());
            categoryProps.add(item);
        }
        param.setCategoryProps(categoryProps);// 类目属性列表

        param.setIsNeedBatch(1);// 是否批次管理 1:是 0:否 （跨境pop须填“是”）
        List<PeriodPropsItem> periodProps = new ArrayList<>();
        for (TikTokPushInfo.Prop prop : tikTokPushInfo.getTikTokPeriodPropList()) {
            PeriodPropsItem item = new PeriodPropsItem();
            PropKey propKey = new PropKey();
            propKey.setPropKeyId(prop.getPropKey().getPropKeyId());
            propKey.setPropKey(prop.getPropKey().getPropKey());
            propKey.setPropCode(prop.getPropKey().getPropCode());
            item.setPropKey(propKey);

            if (prop.getIsMulti()) {
                List<PropValListItem> propValList = new ArrayList<>();
                PropValListItem propValListItem = new PropValListItem();
                propValListItem.setPropValueId(prop.getPropVal().getPropValueId());
                propValListItem.setPropValue(prop.getPropVal().getPropValue());
                propValList.add(propValListItem);
                item.setPropValList(propValList);
            } else {
                PropVal propVal = new PropVal();
                propVal.setPropValueId(prop.getPropVal().getPropValueId());
                propVal.setPropValue(prop.getPropVal().getPropValue());
                item.setPropVal(propVal);
            }
            item.setIsMulti(prop.getIsMulti());
            periodProps.add(item);
        }
        param.setPeriodProps(periodProps);

        List<BatchPropsItem> batchProps = new ArrayList<>();
        for (TikTokPushInfo.Prop prop : tikTokPushInfo.getTikTokBatchPropList()) {
            BatchPropsItem item = new BatchPropsItem();
            PropKey propKey = new PropKey();
            propKey.setPropKeyId(prop.getPropKey().getPropKeyId());
            propKey.setPropKey(prop.getPropKey().getPropKey());
            propKey.setPropCode(prop.getPropKey().getPropCode());
            item.setPropKey(propKey);

            if (prop.getIsMulti()) {
                List<PropValListItem> propValList = new ArrayList<>();
                PropValListItem propValListItem = new PropValListItem();
                propValListItem.setPropValueId(prop.getPropVal().getPropValueId());
                propValListItem.setPropValue(prop.getPropVal().getPropValue());
                propValList.add(propValListItem);
                item.setPropValList(propValList);
            } else {
                PropVal propVal = new PropVal();
                propVal.setPropValueId(prop.getPropVal().getPropValueId());
                propVal.setPropValue(prop.getPropVal().getPropValue());
                item.setPropVal(propVal);
            }
            item.setIsMulti(prop.getIsMulti());
            batchProps.add(item);
        }
        param.setBatchProps(batchProps);// 批次管理属性列表（需要批次管理时填写；跨境pop须将“生产批号采集”、“入库业务单号”、“入库日期”填写“是”）

        param.setIsNeedValid(1);// 是否需要效期管理 1:是 0:否

        List<SkusItem> skus = new ArrayList<>();
        SkusItem skusItem = new SkusItem();
        List<SkuPropsItem> skuProps = new ArrayList<>();
        for (TikTokPushInfo.Prop prop : tikTokPushInfo.getTikTokSalePropList()) {
            SkuPropsItem item = new SkuPropsItem();
            PropKey propKey = new PropKey();
            propKey.setPropKeyId(prop.getPropKey().getPropKeyId());
            propKey.setPropKey(prop.getPropKey().getPropKey());
            propKey.setPropCode(prop.getPropKey().getPropCode());
            item.setPropKey(propKey);

            PropVal propVal = new PropVal();
            propVal.setPropValueId(prop.getPropVal().getPropValueId());
            propVal.setPropValue(prop.getPropVal().getPropValue());
            item.setPropVal(propVal);
            skuProps.add(item);
        }
        List<SkuCategoryPropsItem> skuCategoryProps = new ArrayList<>();
        // 重新处理SkuCategoryProp
        assembledSkuCategoryProp(tikTokPushInfo.getTikTokSkuCategoryPropList(), storeProduct, storeProductAttrValue);
        for (TikTokPushInfo.Prop prop : tikTokPushInfo.getTikTokSkuCategoryPropList()) {
            SkuCategoryPropsItem item = new SkuCategoryPropsItem();
            PropKey propKey = new PropKey();
            propKey.setPropKeyId(prop.getPropKey().getPropKeyId());
            propKey.setPropKey(prop.getPropKey().getPropKey());
            propKey.setPropCode(prop.getPropKey().getPropCode());
            item.setPropKey(propKey);

            if (prop.getIsMulti()) {
                List<PropValListItem> propValList = new ArrayList<>();
                PropValListItem propValListItem = new PropValListItem();
                propValListItem.setPropValueId(prop.getPropVal().getPropValueId());
                propValListItem.setPropValue(prop.getPropVal().getPropValue());
                propValList.add(propValListItem);
                item.setPropValList(propValList);
            } else {
                PropVal propVal = new PropVal();
                propVal.setPropValueId(prop.getPropVal().getPropValueId());
                propVal.setPropValue(prop.getPropVal().getPropValue());
                item.setPropVal(propVal);
            }
            item.setIsMulti(prop.getIsMulti());
            skuCategoryProps.add(item);
        }
        skusItem.setSkuProps(skuProps);
        skusItem.setSkuCategoryProps(skuCategoryProps);
        // 1.2 上传图片
        String image = uploadImage(storeProduct.getId() + "/" + storeProductAttrValue.getId()
                , storeProductAttrValue.getImage()
                , accessToken
                , null);
        skusItem.setImage(image);
        skus.add(skusItem);
        param.setSkus(skus);

        param.setBusinessModel("/");// 经营模式（跨境pop：/）
    }

    private void assembledSkuCategoryProp(List<TikTokPushInfo.Prop> tikTokSkuCategoryPropList, StoreProduct storeProduct, StoreProductAttrValue storeProductAttrValue) {
        for (TikTokPushInfo.Prop prop : tikTokSkuCategoryPropList) {
            String propCode = prop.getPropKey().getPropCode();
            if ("barcode".equals(propCode)) {
                prop.getPropVal().setPropValue(storeProduct.getKeyword() + "_" + storeProductAttrValue.getId());
            } else if ("erp_sku_id".equals(propCode)) {
                prop.getPropVal().setPropValue(storeProduct.getId() + "_" + storeProductAttrValue.getId());
            } else if ("length".equals(propCode) || "wide".equals(propCode) || "high".equals(propCode)) {
                prop.getPropVal().setPropValue("10");
            } else if ("volume".equals(propCode)) {
                prop.getPropVal().setPropValue("100");
            } else if ("gross_weight".equals(propCode)) {
                prop.getPropVal().setPropValue("1");
            }
        }
    }

    private void assembledProduct(ProductAddV2Param param, OrderProductContext context, StoreProduct storeProduct, List<StoreProductAttrValue> storeProductAttrValues, List<String> validateList, AccessToken accessToken) {
        TikTokPushInfo tikTokPushInfo = context.getTikTokPushInfo();
        List<TikTokPushInfo.Prop> tikTokCategoryPropList = tikTokPushInfo.getTikTokCategoryPropList();
        StoreProductDescription storeProductDescription = context.getStoreProductDescription();
        param.setProductType(0L);
        param.setCategoryLeafId(tikTokPushInfo.getCategoryId());
        param.setName(tikTokPushInfo.getProductName());
        param.setPresellConfigLevel(0L);
        param.setWithSkuType(true);
        param.setOuterProductId(storeProduct.getId().toString());
        param.setOutProductId(storeProduct.getId().longValue());
        param.setReduceType(1L);
        param.setFreightId(0L);
        param.setMobile("40012345");
        param.setCommit(true);
        param.setDeliveryDelayDay(15L);
        param.setNeedCheckOut(false);
        if (!Objects.isNull(tikTokPushInfo.getPreSellType())) {
            param.setPresellType(tikTokPushInfo.getPreSellType());
        }
        Long brandId = tikTokPushInfo.getTikTokCategoryPropList().stream().filter(r -> "brand".equals(r.getPropKey().getPropCode()))
                .map(TikTokPushInfo.Prop::getPropVal)
                .map(com.doudian.open.api.supplyChain_batchGetCargoDetail.data.PropVal::getPropValueId)
                .findFirst().orElse(null);

//        Long brandId = tikTokPushInfo.getTikTokProductPropList().stream()
//                .filter(r -> 1687 == r.getPropertyId())
//                .map(TikTokPushInfo.ProductProp::getValue)
//                .map(TikTokPushInfo.ProductProp.Value::getValueId)
//                .findFirst().orElse(null);

        param.setStandardBrandId(brandId);

//        priceUtil.calcProductValuePrice(storeProductAttrValues, context.getMerId(), storeProduct, AreaTypeEnum.CN.getType(), null, false, null, true, null);
        // 规格预处理
//        specExecute(storeProduct, storeProductAttrValues);
        param.setSpecInfo(getSpecs(storeProductAttrValues));
        param.setSpecPricesV2(getSpecsPrices(storeProduct, tikTokPushInfo, storeProductAttrValues, context.getPublishCargoDataList()));
        param.setProductFormatNew(getProductFormant(tikTokPushInfo.getTikTokProductPropList()));

        OpenLogisticsInfo openLogisticsInfo = new OpenLogisticsInfo();
        Long countryId = tikTokCategoryPropList.stream().filter(e -> e.getPropKey().getPropCode().equals("brand_location"))
                .map(TikTokPushInfo.Prop::getPropVal)
                .map(com.doudian.open.api.supplyChain_batchGetCargoDetail.data.PropVal::getPropValueId)
                .findFirst().orElse(0L);
        openLogisticsInfo.setCustomsClearType(2L);
        openLogisticsInfo.setOriginCountryId(countryId);
        openLogisticsInfo.setSourceCountryId(countryId);
        openLogisticsInfo.setBrandCountryId(countryId);
        openLogisticsInfo.setTaxPayer(0L);
        openLogisticsInfo.setNetWeightQty(0.00);
        param.setOpenLogisticsInfo(openLogisticsInfo);
        param.setBizKind(2L);
        param.setPriceHasTax("1");

        List<String> sliderImagelist = JSONArray.parseArray(storeProductDescription.getSliderImage(), String.class);
        // TODO
        List<String> sp1List = JSONArray.parseArray(storeProductDescription.getSp1(), String.class);
        if (CollectionUtils.isEmpty(sliderImagelist)) {
            validateList.add("主图不能为空");
            return;
        }
        if (CollectionUtils.isEmpty(sp1List)) {
            validateList.add("轮播图不能为空");
            return;
        }
        logger.info("抖店推送【创建商品】=====>>>上传Pic开始" + JSON.toJSONString(sliderImagelist));
        List<String> picList = uploadProductImage(sliderImagelist,
                storeProduct.getId() + "_" + "si",
                accessToken, 3L);
        logger.info("抖店推送【创建商品】=====>>>上传Pic结束>>>"+ JSON.toJSONString(picList));

        logger.info("抖店推送【创建商品】=====>>>上传Desc开始" + JSON.toJSONString(sp1List));
        List<String> descList = uploadProductImage(sp1List,
                storeProduct.getId() + "_" + "sp1",
                accessToken, 3L);
        logger.info("抖店推送【创建商品】=====>>>上传Desc结束>>>"+ JSON.toJSONString(descList));
        picList.add(descList.get(0));
        // 要是有两张就取两张图片，没有的话就两次都给第一张图片
        if(descList.size() >= 2) {
            picList.add(descList.get(1));
        }else {
            picList.add(descList.get(0));
        }
        param.setPic(String.join("|", picList));
        param.setDescription(String.join("|", descList));
    }

//    private void specExecute(StoreProduct storeProduct, List<StoreProductAttrValue> storeProductAttrValues) {
//        String colorCode = storeProduct.getColorCode();
//        if (StringUtils.isBlank(colorCode)) return;
//        List<JSONObject> attrValuesJSON = storeProductAttrValues.stream().map(StoreProductAttrValue::getAttrValue)
//                .map(JSON::parseObject).collect(Collectors.toList());
//
//    }

    private String getProductFormant(List<TikTokPushInfo.ProductProp> tikTokProductPropList) {
        JSONObject jsonObject = new JSONObject();
        for (TikTokPushInfo.ProductProp productProp : tikTokProductPropList) {
            if (CollectionUtils.isEmpty(productProp.getValueList()) && StringUtils.isBlank(productProp.getValue().getName())) {
                continue;
            }
            JSONObject obj = new JSONObject();
            // 单条
            if (CollectionUtils.isEmpty(productProp.getValueList())) {
                TikTokPushInfo.ProductProp.Value value = productProp.getValue();
                obj.put("name", value.getName());
                obj.put("value", value.getValueId());
                obj.put("diy_type", productProp.getDiyType());
                List<Object> valueList = new ArrayList<>();
                valueList.add(obj);
                jsonObject.put(productProp.getPropertyId().toString(), valueList);
            } else {
                List<Object> valueList = new ArrayList<>();
                for (TikTokPushInfo.ProductProp.Value value : productProp.getValueList()) {
                    obj.put("name", value.getName());
                    obj.put("diy_type", productProp.getDiyType());
                    obj.put("value", value.getValueId());
                }
                valueList.add(obj);
                jsonObject.put(productProp.getPropertyId().toString(), valueList);
            }
        }
        return jsonObject.toJSONString();
    }

    private SpecInfo getSpecs(List<StoreProductAttrValue> storeProductAttrValues) {
        List<JSONObject> attrValueObjects = storeProductAttrValues.stream()
                .map(StoreProductAttrValue::getAttrValue)
                .map(JSON::parseObject)
                .collect(Collectors.toList());

        Map<Object, List<Map.Entry<String, Object>>> specsMap = attrValueObjects.stream().map(JSONObject::entrySet)
                .flatMap(Set::stream)
                .collect(Collectors.groupingBy(Map.Entry::getKey));

        SpecInfo specInfo = new SpecInfo();
        ArrayList<SpecValuesItem> specValues = new ArrayList<>();
        for (Map.Entry<Object, List<Map.Entry<String, Object>>> entry : specsMap.entrySet()) {
            SpecValuesItem item = new SpecValuesItem();
            item.setPropertyName(entry.getKey().toString());
            List<ValuesItem_4> values = new ArrayList<>();
            List<String> valuesFit = new ArrayList<>();
            for (Map.Entry<String, Object> cEntity : entry.getValue()) {
                ValuesItem_4 item4 = new ValuesItem_4();
                String string = cEntity.getValue().toString();
                if (valuesFit.contains(string)) continue;
                item4.setValueName(string);
                values.add(item4);
                valuesFit.add(string);
            }
            item.setValues(values);
            specValues.add(item);
        }
        specInfo.setSpecValues(specValues);
        return specInfo;
    }

    private List<SpecPricesV2Item> getSpecsPrices(StoreProduct storeProduct, TikTokPushInfo tikTokPushInfo, List<StoreProductAttrValue> storeProductAttrValues, List<JSONObject> publishCargoDataList) {
        List<SpecPricesV2Item> specPricesV2 = new ArrayList<>();
        for (int i = 0; i < storeProductAttrValues.size(); i++) {
            StoreProductAttrValue storeProductAttrValue = storeProductAttrValues.get(i);
            String attrValue = storeProductAttrValue.getAttrValue();
            SpecPricesV2Item specPricesV2Item = new SpecPricesV2Item();
            specPricesV2Item.setSkuStatus(storeProductAttrValue.getStock() != 0);
            specPricesV2Item.setSkuType(1L);
            specPricesV2Item.setStockNum(0L);
            // 计算金额
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("merId", tikTokPushInfo.getMerId());
            THREAD_LOCAL.set(jsonObject);

            ChannelMerchant mockChannelMerchant = new ChannelMerchant();
            BigDecimal purchasePrice = storeProductAttrValue.getPrice();
            specPricesV2Item.setSupplyPrice(purchasePrice.multiply(new BigDecimal("100")).longValue());

            BigDecimal taxPriceNew = priceUtil.getTaxPriceNew(storeProduct, AreaTypeEnum.CN.getType(),
                    purchasePrice, mockChannelMerchant, purchasePrice, false, false, true);

            specPricesV2Item.setPrice(purchasePrice.add(taxPriceNew).setScale(2, RoundingMode.DOWN).multiply(new BigDecimal("100")).longValue());

            specPricesV2Item.setStepStockNum(0L);
            specPricesV2Item.setSupplierId("");
            specPricesV2Item.setOutSkuId(storeProductAttrValue.getId().longValue());
            specPricesV2Item.setOuterSkuId(storeProductAttrValue.getId().toString());
            specPricesV2Item.setCustomsReportInfo(new CustomsReportInfo());
            ArrayList<String> barcodes = new ArrayList<>();
            barcodes.add(storeProductAttrValue.getBarCode());
            specPricesV2Item.setBarcodes(barcodes);

            Cargo cargo = new Cargo();
            // 货品ID
            cargo.setCargoId(publishCargoDataList.get(i).getJSONArray("results").getJSONObject(0).getString("cargoCode"));
            cargo.setSourceType(3L);
            specPricesV2Item.setCargo(cargo);

            specPricesV2Item.setDeliveryInfos(new ArrayList<>());

            JSONObject attrValueJson = JSONArray.parseObject(attrValue);
            List<SellPropertiesItem> sellProperties = new ArrayList<>();
            for (Map.Entry<String, Object> entry : attrValueJson.entrySet()) {
                String key = entry.getKey();
                String val = entry.getValue().toString();
                SellPropertiesItem sellPropertiesItem = new SellPropertiesItem();
                sellPropertiesItem.setPropertyName(key);
                sellPropertiesItem.setValueName(val);
                sellProperties.add(sellPropertiesItem);
            }

            Map<String, Long> stockNumMap = new HashMap<>();
            stockNumMap.put(tikTokPushInfo.getOutWarehouseId(), storeProductAttrValue.getStock().longValue());
            specPricesV2Item.setStockNumMap(stockNumMap);
            specPricesV2Item.setSellProperties(sellProperties);
            specPricesV2.add(specPricesV2Item);
        }
        return specPricesV2;
    }


    /**
     * 上传图片 默认重试 3次
     *
     * @param preFileName
     * @param image
     * @param accessToken
     * @return
     */
    private String uploadImage(String preFileName, String image, AccessToken accessToken, Long tryTimes) {
        String fileExtension = getFileExtension(image);
        if (Objects.isNull(tryTimes) || tryTimes <= 0) {
            tryTimes = 3L;
        }
        preFileName += "货品预览图" + fileExtension;
        // 下载素材
        byte[] bytes = uploadImageRequest(image);
        if (bytes == null) {
            return null;
        }
        BinaryMaterialUploadResponseWrapper r = new BinaryMaterialUploadResponseWrapper();
        for (int i = 0; i < tryTimes; i++) {
            // 获取上传参数
            BinaryMaterialUploadExecutor executor = BinaryMaterialUpload.getDefaultUpload();
            BinaryMaterialUploadParam t = new BinaryMaterialUploadParam();
            // setExtension设置上传文件后缀名称，必须以.开头
            t.setExtension(fileExtension);
            // setBinaryBytes 设置需要上传文件的二进制bytes
            t.setBinaryBytes(bytes);
            r = executor.execute(t, accessToken);
            if (r.isSuccess()) {
                break;
            }
        }

        if (r.isSuccess()) {
            for (int i = 0; i < tryTimes; i++) {
                SupplyChainUploadImageRequest request = new SupplyChainUploadImageRequest();
                SupplyChainUploadImageParam param = request.getParam();
                param.setImageUri(r.getData().getUri());
                SupplyChainUploadImageResponse response = request.execute(accessToken);
                if (response.isSuccess()) {
                    return response.getData().getImage();
                }
            }
        }
        return null;
    }

    /**
     * 上传图片 默认重试 3次
     *
     * @param accessToken
     * @return
     */
    private List<String> uploadProductImage(List<String> images, String preName, AccessToken accessToken, Long tryTimes) {
        List<String> imageUrls = new ArrayList<>();
        if (Objects.isNull(tryTimes) || tryTimes <= 0) {
            tryTimes = 3L;
        }
        MaterialBatchUploadImageSyncRequest request = new MaterialBatchUploadImageSyncRequest();
        MaterialBatchUploadImageSyncParam param = request.getParam();
        param.setNeedDistinct(true);
        ArrayList<MaterialsItem> materials = new ArrayList<>();
        param.setMaterials(materials);

        for (int i = 0; i < tryTimes; i++) {
            for (int j = 0; j < images.size(); j++) {
                MaterialsItem materialsItem = new MaterialsItem();
                materialsItem.setFolderId("0");
                materialsItem.setRequestId(preName + j);
                materialsItem.setName(preName + "_" + j);
                materialsItem.setUrl(images.get(j));
                materialsItem.setMaterialType("photo");
                materials.add(materialsItem);
            }
            MaterialBatchUploadImageSyncResponse response = request.execute(accessToken);
            logger.info("抖店推送【上传图片】=====>>>开始>>>[" + "重试次数" + i + "]" + JSON.toJSONString(request));
            logger.info("抖店推送【上传图片】=====>>>开始>>>[" + "重试次数" + i + "]" + JSON.toJSONString(response));
            if (response.isSuccess()) {
                Map<String, SuccessMapItem> successMap = response.getData().getSuccessMap();
                List<String> materialIdList = successMap.entrySet().stream()
                        .map(Map.Entry::getValue)
                        .map(SuccessMapItem::getMaterialId)
                        .collect(Collectors.toList());

                // 休眠5秒 降低 查询查不到的问题
                try {
                    long millis = 5000L;
                    logger.info("抖店推送【创建货品】=====>>>休眠" + millis + "ms");
                    Thread.sleep(millis);
                } catch (InterruptedException e) {
                }

                for (String materialIds : materialIdList) {
                    for (int k = 0; k < tryTimes; k++) {
                        MaterialQueryMaterialDetailRequest queryRequest = new MaterialQueryMaterialDetailRequest();
                        MaterialQueryMaterialDetailParam queryParam = queryRequest.getParam();
                        queryParam.setMaterialId(materialIds);
                        MaterialQueryMaterialDetailResponse queryResponse = queryRequest.execute(accessToken);
                        logger.info("抖店推送【上传图片】=====>>>获取图片素材链接地址>>>[" + "重试次数" + k + "]" + JSON.toJSONString(queryRequest));
                        logger.info("抖店推送【上传图片】=====>>>获取图片素材链接地址>>>[" + "重试次数" + k + "]" + JSON.toJSONString(queryResponse));
                        if (queryResponse.isSuccess()) {
                            MaterialInfo materialInfo = queryResponse.getData().getMaterialInfo();
                            if (materialInfo.getAuditStatus() == 3) {
                                imageUrls.add(materialInfo.getByteUrl());
                                break;
                            }
                        }
                    }
                }

                if (imageUrls.size() == images.size()) {
                    break;
                }
            }
        }

        return imageUrls;
    }

    private byte[] uploadImageRequest(String url) {
        restTemplate = new RestTemplate();
        try {
            ResponseEntity<byte[]> resp = restTemplate.getForEntity(url, byte[].class);
            return resp.getBody();
        } catch (Exception e) {
            return null;
        }
    }

    private String getFileExtension(String image) {
        String lowerCase = image.toLowerCase();
        if (lowerCase.contains(".png")) {
            return ".png";
        } else {
            return ".jpg";
        }
    }
}
